package com.ld.task;

import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CyclicBarrier;

/**
 * CyclicBarrier:放行条件由一组线程本身决定
 */
public class UseCyclicBarrier {
    //     static CyclicBarrier cyclicBarrier = new CyclicBarrier(6);
    //6个线程都执行到await()方法时，会先执行AfterWork()线程，AfterWork()线程执行完成后在继续向下执行。
    static CyclicBarrier cyclicBarrier = new CyclicBarrier(6, new AfterWork());
    //    List<String> threadNames = new ArrayList<>();
    static ConcurrentHashMap<String, Object> concurrentHashMap = new ConcurrentHashMap<>(); //线程安全的集合

    static class WorkTask implements Runnable {
        @Override
        public void run() {
            try {
                concurrentHashMap.put(Thread.currentThread().getName(), Thread.currentThread().getId());
                Random r = new Random();
                if (r.nextBoolean()) {
                    System.out.println("线程" + Thread.currentThread().getName() + "做点别的事情...");
                    Thread.sleep(2000);
                }
                System.out.println("线程" + Thread.currentThread().getName() + "进入等待状态...");
                cyclicBarrier.await();//线程运行到此处等待的数量达到设定的初始值后，就会自动向下进行。
                Thread.sleep(1000);
                System.out.println("线程" + Thread.currentThread().getName() + "开始向下执行...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }

    static class AfterWork implements Runnable {
        @Override
        public void run() {
            if (!concurrentHashMap.isEmpty()) {
                for (String name : concurrentHashMap.keySet()) {
                    System.out.println("AfterWork:" + name);
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 6; i++) {
//            Thread.sleep(1000);
            new Thread(new WorkTask()).start();
        }
    }
}
